package com.csd.serviceImpl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.csd.dao.MessageDAO;
import com.csd.dao.ProjectDAO;
import com.csd.dao.ScoreDAO;
import com.csd.dao.TeacherDAO;
import com.csd.exception.DeleteException;
import com.csd.exception.GetException;
import com.csd.exception.SaveException;
import com.csd.exception.UpdateException;
import com.csd.helper.IConstant;
import com.csd.helper.ProjectState;
import com.csd.helper.SessionManager;
import com.csd.helper.Tool;
import com.csd.pojo.ChangeRecord;
import com.csd.pojo.EvaluateItem;
import com.csd.pojo.Message;
import com.csd.pojo.Project;
import com.csd.pojo.ProjectType;
import com.csd.pojo.Score;
import com.csd.pojo.Teacher;
import com.csd.pojo.Team;
import com.csd.service.IProjectService;
import com.csd.vo.ProjectVO;
import com.csd.vo.TeacherTaskVO;
import commons.netmail.MailData;
import commons.netmail.MailMeta;

/**
 * 项目业务逻辑
 * 
 * @author 尹华彬，刘世彬，sanmu <br>
 *         创建于2009-12-17
 */
public class ProjectService implements IProjectService {

	private MessageDAO messageDAO;
	private ScoreDAO scoreDAO;

	public MessageDAO getMessageDAO() {
		return messageDAO;
	}

	public void setMessageDAO(MessageDAO messageDAO) {
		this.messageDAO = messageDAO;
	}

	/**
	 * 团队申请结题
	 * @return true为申请结题成功,false 申请失败
	 */
  
	public boolean applyEnd() {
		boolean tag = false;
		try {
			Integer id = SessionManager.getUserID();
			if (id != null) {
				List list = projectDAO.findByTeam(id);
				if (list != null && list.size() > 0) 
				{
					Project project = (Project) list.get(0);
					if (project != null) 
					{
						project.setState(ProjectState.finishApply);
						projectDAO.update(project);
						tag = true;
					}
				}
			}

		} catch (RuntimeException re) {
			throw new UpdateException(re, "申请结题异常");
		}

		return tag;
	}

	/**
	 * 查询未受理的新项目申请
	 * 
	 * @return 项目对象列表
	 */
	@SuppressWarnings("unchecked")
	public List<Project> listUnhandleProject() 
	{
		List<Project> unhandleList = null;
		try {
			unhandleList = projectDAO.findByProperty("state", ProjectState.apply);
		} catch (RuntimeException re) {
			throw new GetException(re, "查询处于已申请未处理的工程异常");
		}
		return unhandleList;
	}
	
	/**
	 * 项目申请指导老师确认是否通过并更新项目
	 * @param id ,result
	 *    项目ID , 结题的结果
	 * @return 项目对象列表
	 */
	public boolean updateReviewProject(Integer projectID , String result)
	{
			Project project = projectDAO.findById(projectID);
			
			/**
			 * @description 指导老师驳回申请项目，发送驳回电子邮件给项目团队的队长
			 */
			MailData mailData = new MailData(project.getTeam().getStudent().getEmail(), 
					project.getTeam().getName(), MailMeta.getTeacherRejectInfo("萌芽基金", project.getProjectname()), 
					MailMeta.getQuickLink(), MailMeta.getContact());
			new Thread(mailData).start();

			if (result.equals("pass")) 
			{
				project.setState(ProjectState.apply);
			} 
			else if (result.equals("reject")) 
			{
				//如果被拒绝，处理方式为给团队发送一个消息，如果团队想要结题，必须重新申请			
				Message message = new Message();
				message.setIsnew(true);
				message.setReceiverid(IConstant.teamRole + project.getTeam().getId());
				message.setSenderid(IConstant.teacherRole + project.getTeacher().getId());
				message.setTime(new Date());
				message.setTitle("项目申请报告被指导老师驳回");
				message.setContent("提示：团队的项目申请报告不符合要求, 指导老师审核未通过.请与指导老师联系并重新提交项目申请报告.");
				messageDAO.save(message);
				project.setState(ProjectState.metaphaseEnd);
			} 
			
			try 
			{
				projectDAO.update(project);
			} catch (RuntimeException re) 
			{
				throw new UpdateException(re, "更新工程异常");
			}

			return true;
	}
    
	/**
	 * 结题申请是否通过并更新项目
	 * @param id ,result
	 *    项目ID , 结题的结果
	 * @return 项目对象列表
	 */
	public boolean updateProject(Integer id, String result) {

		Project project = projectDAO.findById(id);

		if (result.equals("pass")) 
		{
			project.setState(ProjectState.telophasePass);
		} 
		else if (result.equals("reject")) 
		{
			//如果被拒绝，处理方式为给团队发送一个消息，如果团队想要结题，必须重新申请			
			Message message = new Message();
			message.setIsnew(true);
			message.setReceiverid(IConstant.teamRole + project.getTeam().getId());
			message.setSenderid(IConstant.teacherRole + project.getTeacher().getId());
			message.setTime(new Date());
			message.setTitle("结题申请报告被驳回");
			message.setContent("提示：团队的申请结题报告, 指导老师审核未通过.请与指导老师联系并重新提交结题报告.");
			messageDAO.save(message);
			project.setState(ProjectState.metaphaseEnd);
		} else {
			System.out.println("老师审核结题出错");
		}
		try {
			projectDAO.update(project);
		} catch (RuntimeException re) {
			throw new UpdateException(re, "更新工程异常");
		}

		return true;
	}

	public TeacherDAO getTeacherDAO() {
		return teacherDAO;
	}

	public void setTeacherDAO(TeacherDAO teacherDAO) {
		this.teacherDAO = teacherDAO;
	}

	private ProjectDAO projectDAO;
	/** teacherDao */
	private TeacherDAO teacherDAO;
	/**
	 * 删除项目
	 * @param id
	 *        项目ID
	 * @return true为申请结题成功,false 申请失败
	 */
  
	public boolean deleteProject(Integer id) {
		Project project = null;
		project = projectDAO.findById(id);
		try {
			projectDAO.delete(project);
		} catch (RuntimeException re) {

			throw new DeleteException(re,"删除工程异常");
		}
		return true;
	}

	public ProjectDAO getProjectDAO() {
		return projectDAO;
	}

	public void setProjectDAO(ProjectDAO projectDAO) {
		this.projectDAO = projectDAO;
	}
	/**
	 * 查询项目
	 * @param id
	 *        项目ID
	 * @return project 为项目实例
	 */

	public Project getProjectByID(Integer id) {
		Project project = null;
		try {
			project = projectDAO.findById(id);
		} catch (RuntimeException re) {
			throw new GetException(re,"查询工程异常");
		}
		return project;
	}
    
	/**
	 * 查询团队是否可以申请项目
	 * @param id
	 *        项目ID
	 * @return true 为可以申请，false 为不能申请
	 */
	public boolean isEnableApply() {
		boolean tag = true;
		try {
			Integer id = SessionManager.getUserID();
			List list = projectDAO.findByTeam(id);
			if (list != null && list.size() > 0)
				tag = false;
		} catch (RuntimeException re) {
			throw new GetException(re,"团队项目可申请状态查询异常");
		}
		return tag;
	}
	
	/**
	 * 获得指导项目
	 * @param teacherID
	 *        老师ID
	 * @return guideList 为老师指导的项目列表
	 */
	public List<Project> listProjectByTeacherID(Integer teacherID) {
		List<Project> guideList = null;
		Teacher teacher = teacherDAO.findById(teacherID);
		guideList = projectDAO.findByProperty("teacher", teacher);
		return guideList;
	}

	
	/**
	 * 通过团队信息查找项目
	 * @param id
	 *        团队ID
	 * @return projectList 获得团队申请的项目列表
	 */
	public List<Project> listProjectByTeam(Integer id) {
		List<Project> projectList = null;
		try {
			projectList = projectDAO.findByTeam(id);
		} catch (RuntimeException re) {
			throw new GetException(re,"查询团队的工程异常");
		}
		return projectList;
	}

	/**
	 * 通过老师ID 获得项目的审批结题任务
	 * @param teacherID
	 *        老师ID
	 * @return projects 为需要审批结题的项目 
	 */
	public List<Project> listFinTaskByTeacherID(Integer teacherID) {

		List<Project> projects = null;
		try {
			projects = projectDAO.listFinTaskByTeacherID(teacherID);
		} catch (RuntimeException re) {
			throw new GetException(re,"列出项目最后任务异常");
		}

		return projects;
	}

	/**
	 * 把老师需要审批的项目转换为老师任务的VO
	 * @param evaluateList
	 *        老师需要评审的任务列表
	 * @return teacherEvaluateList 老师评审任务的VO
	 */
	public List<TeacherTaskVO> listProjectByList(List<EvaluateItem> evaluateList) {
		List<TeacherTaskVO> teacherEvaluateList = new ArrayList<TeacherTaskVO>();
		Project project = null;
		try {
			for (Iterator<EvaluateItem> i = evaluateList.iterator();; i
					.hasNext()) {
				TeacherTaskVO teacherTaskVO = new TeacherTaskVO();
				EvaluateItem eItem = i.next();
				project = eItem.getProject();
				teacherTaskVO.setProjectID(project.getId());
				teacherTaskVO.setEvaluateID(eItem.getId());
				teacherTaskVO.setEvaluateStage(eItem.getStage());
				teacherTaskVO.setProjectName(project.getProjectname());
				teacherTaskVO
						.setLeader(project.getTeam().getLeader().getName());
				teacherTaskVO
						.setProjectType(project.getProjectType().getName());
				teacherEvaluateList.add(teacherTaskVO);
			}
		} catch (RuntimeException re) {
			System.out.println("ProjectService。listProjectByList()");
		}
		return teacherEvaluateList;
	}
   
	/**
	 * 把老师需要审批的变更转换为老师任务的VO
	 * @param changRecordList
	 *        老师需要评审的变更列表
	 * @return teacherChangeList 老师评审变更的VO
	 */
	public List<TeacherTaskVO> listProjectByChangeList(List<ChangeRecord> changRecordList) 
	{
		List<TeacherTaskVO> teacherChangeList = new ArrayList<TeacherTaskVO>();
		Project project = null;
		try {
			for (Iterator<ChangeRecord> i = changRecordList.iterator();; i
					.hasNext()) {
				TeacherTaskVO teacherTaskVO = new TeacherTaskVO();
				ChangeRecord changeRecord = i.next();
				project = changeRecord.getProject();
				teacherTaskVO.setEvaluateStage(null);
				teacherTaskVO.setProjectID(project.getId());
				teacherTaskVO.setChangeID(changeRecord.getId());
				teacherTaskVO
						.setLeader(project.getTeam().getLeader().getName());
				teacherTaskVO.setProjectName(project.getProjectname());
				teacherTaskVO
						.setProjectType(project.getProjectType().getName());
				teacherChangeList.add(teacherTaskVO);
			}
		} catch (Exception e) {
			System.out.println("ProjectService。listProjectByChangeList()");
		}
		return teacherChangeList;
	}
    
	/**
	 * 把老师需要审批的结题转换为老师任务的VO
	 * @param projectList
	 *        申请结题的项目列表
	 * @return teacherFianlTaskList 老师结题任务的VO
	 */
	public List<TeacherTaskVO> listProjectByFinalList(List<Project> projectList) 
	{
		List<TeacherTaskVO> teacherFianlTaskList = new ArrayList<TeacherTaskVO>();
		Project project = null;
		try 
		{
			for (Iterator<Project> i = projectList.iterator();; i.hasNext()) 
			{
				TeacherTaskVO teacherTaskVO = new TeacherTaskVO();
				project = i.next();
				teacherTaskVO.setEvaluateStage(null);
				teacherTaskVO.setLeader(project.getTeam().getLeader().getName());
				teacherTaskVO.setProjectID(project.getId());
				teacherTaskVO.setProjectName(project.getProjectname());
				teacherTaskVO.setProjectType(project.getProjectType().getName());
				teacherFianlTaskList.add(teacherTaskVO);
			}
		} catch (Exception e) 
		{
		}
		return teacherFianlTaskList;
	}
	/**
	 * 保存项目
	 * @param project
	 *        项目实例
	 * @return true为保存成功,false 为保存失败
	 */
   
	public boolean saveProject(Project project) {
		try {
			Integer id = SessionManager.getUserID();
			if (id != null) {
				List list = projectDAO.findByTeam(id);
				if (list == null || list.size() == 0) {
					Team team = new Team();
					team.setId(id);
					project.setApplytime(Tool.getCurrentDate());
					project.setProjectnum("" + id);
					project.setTeam(team);
					project.setState(ProjectState.waitReview);
					project.setFinalscore("-1");
					projectDAO.save(project);
					Score score = new Score();
					score.setProject(project);
					scoreDAO.save(score);
				}
			}

		} catch (RuntimeException re) {
			throw new SaveException(re,"申请工程异常");
		}
		return true;
	}

	public ScoreDAO getScoreDAO() {
		return scoreDAO;
	}

	public void setScoreDAO(ScoreDAO scoreDAO) {
		this.scoreDAO = scoreDAO;
	}
   
	/**
	 * 更新项目
	 * @param project
	 *        项目实例
	 * @return true为保存成功,false 为保存失败
	 */
	public boolean updateProject(Project project) {
		try {
			projectDAO.update(project);
		} catch (RuntimeException re) {
			throw new UpdateException(re,"更新工程信息异常");
		}
		return true;
	}

	/**
	 * 获得团队项目列表
	 * @return list为团队申请项目列表
	 */
	public List<Project> listTeamProject() {
		List<Project> list = null;

		try {
			int teamID = SessionManager.getUserID();
			list = projectDAO.findByProperty("team.id", teamID);
		} catch (RuntimeException re) {
			throw new GetException(re,"列出团队项目异常");
		}

		return list;
	}

	/**
	 * 查询历史项目
	 * 
	 * @return 项目对象列表
	 */
	public List<ProjectVO> listHistoryProject() {
		List<ProjectVO> histList = new ArrayList<ProjectVO>();
		List<Project> tempList = null;
		try {
			tempList = projectDAO.findByProperty("state", ProjectState.projectEnd);
			for (Iterator iterator = tempList.iterator(); iterator.hasNext();) {
				Project p = (Project) iterator.next();
				histList.add(new ProjectVO(p.getId(), p.getProjectType()
						.getName(), p.getProjectname(), p.getTeam()
						.getStudent().getName(), Integer.parseInt(p
						.getFinalscore()), p.getApplytime()));
			}
		} catch (RuntimeException re) {
			throw new GetException(re,"列出历史项目异常");
		}
		return histList;
	}

	/**
	 * 查询未受理的项目申请
	 * 
	 * @return 项目对象列表
	 */
	@SuppressWarnings("unchecked")
	public List<ProjectVO> listUnhandleProject(String state) 
	{
		List<ProjectVO> unhandleList = new ArrayList<ProjectVO>();
		List<Project> tempList = null;
		
		try 
		{
			tempList = projectDAO.findByProperty("state", state);
			
			for (Iterator iterator = tempList.iterator(); iterator.hasNext();) 
			{
				Project p = (Project) iterator.next();
				unhandleList.add(new ProjectVO(p.getId(), p.getProjectType()
						.getName(), p.getProjectname(), p.getTeam()
						.getStudent().getName(), -1, p.getApplytime()));
			}
		} 
		catch (RuntimeException re) 
		{
			throw new GetException(re,"列军未处理项目错误");
		}
		return unhandleList;
	}

	/**
	 * 管理员待完成的前期项目通过与否的审查列表
	 * 
	 * @return 项目对象列表
	 */
	public List<ProjectVO> listProjectApplyEvaluate() {
		List<ProjectVO> evaluateList = new ArrayList<ProjectVO>();
		List<Project> tempList = null;
		try {
			tempList = projectDAO.findByProperty("state",
					ProjectState.proHaveScore);
			for (Iterator iterator = tempList.iterator(); iterator.hasNext();) {
				Project p = (Project) iterator.next();
				ProjectVO projectVO = new ProjectVO(p.getId(), p
						.getProjectType().getName(), p.getProjectname(), p
						.getTeam().getStudent().getName(), p.getScore()
						.getProphasescore(), p.getApplytime());

				if (!p.getFinalscore().equals("-1" )) {
					projectVO.setScore(Integer.parseInt(p.getFinalscore()));
				}
				evaluateList.add(projectVO);
			}
		} catch (RuntimeException re) {
			throw new GetException(re,"");
		}
		return evaluateList;
	}
	/**
	 * 根据项目的当前状态 判断其需要到的下一个状态
	 * @param projectID
	 *        项目ID
	 * @return 项目对象列表
	 */
   
	public String changeToNextState(Integer projectID) 
	{
		String stage = null;

		try {
			Project project = projectDAO.findById(projectID);
			if (project != null) {
				if (project.getState().equals(ProjectState.apply)) {
					project.setState(ProjectState.prophase);
					stage = "1";
				}
				if (project.getState().equals(ProjectState.prophasePass)) {
					project.setState(ProjectState.metaphase);
					stage = "2";
				}
				if (project.getState().equals(ProjectState.telophasePass)) {
					project.setState(ProjectState.finishCheck);
					stage = "3";
				}
				projectDAO.update(project);
			}
		} catch (RuntimeException re) {
			throw new UpdateException(re, "");
		}

		return stage;
	}

	/**
	 * 列出未登录成绩的项目
	 * 
	 * @return 项目对象列表
	 */
	public List<ProjectVO> listUnregisterScoreProject(String state) {
		List<ProjectVO> registerScoreProjectList = new ArrayList<ProjectVO>();
		List<Project> tempList = null;
		try {
			tempList = projectDAO.findByProperty("state", state);
			for (Iterator iterator = tempList.iterator(); iterator.hasNext();) {
				Project p = (Project) iterator.next();

				registerScoreProjectList.add(new ProjectVO(p.getId(), p
						.getProjectType().getName(), p.getProjectname(), p
						.getTeam().getStudent().getName(), p.getScore()
						.getProphasescore(), p.getApplytime()));
			}
		} catch (RuntimeException re) {
			throw new GetException(re,"");

		}
		return registerScoreProjectList;
	}

	/**
	 * 列出进行中的项目
	 * 
	 * @return 项目对象列表
	 */
	public List<ProjectVO> listDevelopingProject() {
		List<ProjectVO> developingProjectList = new ArrayList<ProjectVO>();
		List<Project> pList = null;
		try {
			pList = projectDAO.listDevelopingProject();
			for (Iterator iterator = pList.iterator(); iterator.hasNext();) {
				Project p = (Project) iterator.next();
				System.out.println(p.getProjectType() + " = " + p.getTeam()
						+ " = " + p.getTeam().getStudent());
				developingProjectList
						.add(new ProjectVO(p.getId(), p.getProjectType()
								.getName(), p.getProjectname(), p.getTeam()
								.getStudent().getName(), -1, p.getApplytime()));
			}
		} catch (
				RuntimeException re) {

			throw new GetException(re,"");
		}
		return developingProjectList;
	}

	/**
	 * 根据项目id查询其所属于的项目类别
	 * 
	 * @param projectID
	 *            项目id
	 * @return 项目类别
	 */
	public ProjectType findProjectTypeByProjectID(Integer projectID) {
		ProjectType projectType = null;
		Project project = null;
		try {
			project = projectDAO.findById(projectID);
			if (project != null) {
				projectType = project.getProjectType();
			}
		} catch (RuntimeException re) {

			throw new GetException(re,"");
		}
		return projectType;
	}

	/**
	 * 管理员通过或驳回项目申请
	 * 
	 * @param action
	 *            1通过或0驳回
	 * @param level
	 *            项目级别
	 * @return 修改成功返回true
	 */
	public boolean projectApplyPassOrReject(Integer projectID, String action, String level) 
	{
		boolean bl = false;
		Project project = null;
		
		try 
		{
			project = projectDAO.findById(projectID);
			if (project != null) 
			{
				if (action.equals("1")) 
				{
					project.setState(ProjectState.prophasePass);
				} 
				else if (action.equals("0")) 
				{
					/**
					 * @description 管理员驳回申请项目，发送驳回电子邮件给项目团队的队长
					 */
					MailData mailData = new MailData(project.getTeam().getStudent().getEmail(), 
							project.getTeam().getName(), MailMeta.getAdministratorRejectInfo("萌芽基金", project.getProjectname()), 
							MailMeta.getQuickLink(), MailMeta.getContact());
					new Thread(mailData).start();
					project.setState(ProjectState.prophaseReject);
				}
				
				if (level.equals("1"))
				{
					project.setLevel(ProjectState.nationalLevel);
				}
				else if (level.equals("2")) 
				{
					project.setLevel(ProjectState.schoolLevel);
				} 
				else if (level.equals("3")) 
				{
					project.setLevel(ProjectState.academyLevel);
				}
				
				projectDAO.update(project);
			}
			
			bl = true;
		} catch (RuntimeException re) {
			
			throw new UpdateException(re,"");
		}
		return bl;
	}
   
	/**
	 * 列出所有申请的项目列表
	 * @return projects  申请的项目列表
	 */
	public List<Project> listApplyProject(){
		List<Project> projects = null;
		List<Project> list1;
		try {
			projects = projectDAO.findByState(ProjectState.apply);
			list1 = projectDAO.findByState(ProjectState.prophase);
		} catch (RuntimeException re) {
			throw new GetException(re,"");
			//list1 = null;
		}
		projects.addAll(list1);
		return projects;
	}
	
	public List<Project> listWaitReviewProjectByTeacherID(Integer teacherID)
	{
		List<Project> waitReviewProjects = null;
		
		try
		{
			waitReviewProjects = projectDAO.listWaitReviewProjectByTeacherID(teacherID);
		}
		catch(RuntimeException re)
		{
			throw new GetException(re, "查询需要评审的项目失败");
		}
		
		return waitReviewProjects;
	}
	 

	/**
	 * 列出所有评审的项目
	 * @return projects  评审中的项目列表
	 */
	public List<Project> listEvaluateProject()
	{
		List<Project> projects = null;
		try{
		projects = projectDAO.findByState(ProjectState.prophasePass);
		List<Project> list1 = projectDAO.findByState(ProjectState.metaphase);
		List<Project> list2 = projectDAO.findByState(ProjectState.metaphaseEnd);
		List<Project> list3 = projectDAO.findByState(ProjectState.finishApply);
		
        projects.addAll(list1);
        projects.addAll(list2);
        projects.addAll(list3);
	} catch (RuntimeException re) 
	{
		throw new GetException(re,"");
	}
		return projects;
	}
	
	/**
	 * 列出所有结题的项目
	 * @return projects  结题的项目列表
	 */
  	
	public List<Project> listFinshProject(){
		List<Project> projects = null;
		try{
		projects = projectDAO.findByState(ProjectState.telophasePass);
		List<Project> list1 = projectDAO.findByState(ProjectState.finishCheck);
		projects.addAll(list1);
		} catch (RuntimeException re) {
			throw new GetException(re,"");
		}
		return projects;
	}
}
